<?php

namespace Izqut\Membership\Traits;

use Izqut\Membership\Models\Membership;
use Izqut\Membership\Models\UserMembership;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Carbon\Carbon;

trait HasMembership
{
    /**
     * Get all memberships for this user
     */
    public function memberships(): HasMany
    {
        return $this->hasMany(UserMembership::class);
    }

    /**
     * Get the current active membership
     */
    public function membership(): HasOne
    {
        return $this->hasOne(UserMembership::class)
            ->where('is_active', true)
            ->where(function ($query) {
                $query->whereNull('expires_at')
                    ->orWhere('expires_at', '>', now());
            })
            ->latest();
    }

    /**
     * Check if user is VIP member
     */
    public function isVip(): bool
    {
        $membership = $this->membership()->first();

        if (!$membership || !$membership->isActive()) {
            return false;
        }

        return $membership->membership->isVip();
    }

    /**
     * Check if user has an active membership
     */
    public function hasMembership(): bool
    {
        $membership = $this->membership()->first();

        return $membership && $membership->isActive();
    }

    /**
     * Check if user has a specific membership by slug
     */
    public function hasMembershipPlan(string $slug): bool
    {
        $membership = $this->membership()->first();

        if (!$membership || !$membership->isActive()) {
            return false;
        }

        return $membership->membership->slug === $slug;
    }

    /**
     * Subscribe user to a membership plan
     *
     * @param Membership|int $plan
     * @param Carbon|null $startsAt
     * @return UserMembership
     */
    public function subscribe($plan, $startsAt = null)
    {
        if (is_int($plan)) {
            $plan = Membership::findOrFail($plan);
        }

        // Deactivate existing active memberships
        $this->memberships()->where('is_active', true)->update(['is_active' => false]);

        $startsAt = $startsAt ?? now();
        $expiresAt = $plan->isPerpetual() ? null : $startsAt->copy()->addDays($plan->duration_days);

        return $this->memberships()->create([
            'membership_id' => $plan->id,
            'starts_at' => $startsAt,
            'expires_at' => $expiresAt,
            'is_active' => true,
        ]);
    }

    /**
     * Cancel current membership
     */
    public function cancelMembership(): bool
    {
        $membership = $this->membership()->first();

        if (!$membership) {
            return false;
        }

        $membership->deactivate();
        return true;
    }

    /**
     * Get current membership plan
     */
    public function currentMembershipPlan(): ?Membership
    {
        $membership = $this->membership()->first();

        return $membership ? $membership->membership : null;
    }

    /**
     * Get days remaining in current membership
     */
    public function membershipDaysRemaining(): ?int
    {
        $membership = $this->membership()->first();

        return $membership ? $membership->daysRemaining() : null;
    }
}
